package org.p2psimulator.analysis;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.p2psimulator.exceptions.DatasetFailureException;

@SuppressWarnings("unchecked")
public class Info<Label, Key, Value> {

    Map<Label, Map<Key, Value>> map;

    public Map<Label, Map<Key, Value>> getMap() {
        return map;
    }

    public void setMap(Map<Label, Map<Key, Value>> map) {
        this.map = map;
    }

    public Info(Map<Label, Map<Key, Value>> map) {
        super();
        this.map = map;
    }

    public void putValue(Label s, Key k, Value v) {
        Map<Key, Value> seq = map.get(s);

        if (seq == null) {
            seq = new HashMap<Key, Value>();
            map.put(s, seq);
        }

        seq.put(k, v);
    }

    public Value getValue(Label s, Key k) {

        if (!map.containsKey(s)) {
            map.put(s, new HashMap<Key, Value>());
        }

        if (!map.get(s).containsKey(k)) {
            map.get(s).put(k, null);
        }
        return map.get(s).get(k);
    }

    /**
     * Exporta o conte�do interno da informa��o para um container JfreeChart
     *
     * @return
     * @throws DatasetFailureException
     */
    public XYDataset toJFreeChartDataset() throws DatasetFailureException {


//		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        XYSeriesCollection dataset = new XYSeriesCollection();
        for (Label name : map.keySet()) {

            Comparable b = null;
            if (name instanceof Comparable) {
                b = (Comparable) name;
            } else {
                throw new DatasetFailureException("Tipo incompat�vel!");
            }
            XYSeries serie = new XYSeries(b);
            for (Key x : map.get(name).keySet()) {

                Double y = null;
                if (map.get(name).get(x) instanceof Number) {
                    y = (Double) map.get(name).get(x);
                } else {
                    throw new DatasetFailureException("Valor incompat�vel!");
                }

                serie.add((Integer) x, y);
            }
            dataset.addSeries(serie);
        }
        return dataset;
    }

    public void exportToCSVFile(File csv) {
        try {
            String header = "tick;";
            Set<Key> keys = null;
            for (Label l : map.keySet()) {
                header += l.toString() + ";";
                if (keys == null) {
                    keys = map.get(l).keySet();
                }
            }
            if (keys == null) {
                return;
            }
            PrintWriter writer = new PrintWriter(csv);
            writer.println(header);

            for (Key k : keys) {
                writer.print(k + ";");
                for (Label l : map.keySet()) {
                    writer.print(map.get(l).get(k) + ";");
                }
                writer.print('\n');
            }

            writer.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public String toString() {
        StringBuilder str = new StringBuilder();
        for (Label label : map.keySet()) {

            str.append(label + "\n");
            for (Key key : map.get(label).keySet()) {
                str.append(map.get(label).get(key) + " ");
            }
            str.append("\n");
        }
        return str.toString();
    }

    public void clear() {
        this.map.clear();
    }
}
